(8/8)Spawning——生成敌人

大家好,这是官方的教程的最后一部分内容,今天之后就继续文档翻译了,Heartbeast大大的视频我还在看,过阵子慢慢来:)
今天要学习的是如何随机生成敌人,在之前的学习过程中我们都是直接在场景编辑器中添加了几个敌人用来测试游戏的,但是那样有一些问题,比如你放几个敌人就是几个,打完了就没了,那游戏也就无法继续了,不同的玩家之间也缺乏了一个比较的依据,因此我们希望游戏能随着时间不断自动生成敌人,并且敌人的位置是完全随机的,那么我就开始今天的课程。
首先我们在场景编辑器中给敌人单独创建一个实例图层并取名为“EnemyLayer”,然后要记得我们需要调整一下顺序确保飞船所处的图层一直在最上方:

在敌人的图层创建好以后,我们要再创建一个对象,这个对象是用来作为敌人生成器的:

这个对象我们同样采用敌人的精灵作为贴图,但是稍微不同的是,我们需要在创建的时候把这个图设置的很小,如图所示,我们创建了一个Create事件,并在这个事件中写了两行代码:

image_xscale = 0.1 ;
image_yscale = 0.1 ;

这两个属性也是GMS2自带的属性,分别是图像高宽的缩放比例,我们在这里把高宽的缩放都设置为0.1即代表高宽都只有原图的1/10大小,这样就代表这个对象在生成实例时会显示的很小,整体面积只有原图的1/100。我们这个生成器就是希望让敌人有一种慢慢变大最后完全生成的感觉,因此我们还需要写一个方法来使得图像逐渐变大,这里我们应该还能记得在上一课曾经用过一个方法去使得图像的透明度逐渐增加,我们这里用类似的方法即可达到目的,首先我们需要创建一个step事件:

其中我们写了这些内容:

image_xscale = min(image_xscale+0.02,1)
image_yscale = image_xscale ;

if (image_xscale = 1) instance_change(obj_enemy,true);

第一行就跟我们上节课中逐渐增加图片透明图的方法几乎一样,只是这次我们修改的不是图片的透明度,而是图片的宽度的缩放比,同样用min这个方法来反复获得最小值,直至前面image_xscale的值大于1以后就永远被赋值为1即原图大小,第二行我们没有重复这个步骤是因为我们希望图像的高度缩放比跟宽度缩放比完全同步,因此直接将二者相等关联起来即可。
但是这个逐渐变大的图像是敌人生成器,而敌人生成器中没有任何行为逻辑代码,是不能像敌人一样来追赶玩家控制的飞船的,也不可能对玩家射出的子弹和玩家的飞船进行交互和碰撞,那么我们希望的就是这个生成器能变成一个敌人的实例,这里就用到了GMS2的另一个自带的方法instance_change,如上图最后一行。
在最后我们写的那一行意思是,当图像的缩放比与原图完全一致以后,将当前的实例替换为敌人对象的实例,由于我们生成器所使用的图像与敌人的图像完全一致,因此当生成器的图像尺寸达到原图尺寸以后,这个即时的替换是玩家无法察觉的,玩家只会看到一个敌人由小变大然后到达正常尺寸以后就会完全按照敌人的行为逻辑来追赶他控制的飞船,并不会知道前面逐渐变大的那个图像跟后面来追逐他的敌人其实是两个完全不同的实例。
为了测试这个生成器能不能正常工作,我们要去场景编辑器中,将几个生成器的实例放进场景进行测试,这里一定要注意,我们要放进场景的是今天创建的生成器的实例,而非敌人对象本身。
当运行游戏测试通过以后,我们要注意,现在虽然敌人有了一个生成的过程,但是这些敌人依然是我们在场景编辑器中提前放进去的,这些敌人的位置永远在那几个地方,数量也是恒定不变的,这还没有达到我们最初的要求——让敌人随着时间的推移不断增加。
于是我们又需要再创建一个新的对象,这个对象是不可见的,其作用就是在玩家看不到的地方默默地在场景中制造敌人(生成器)。
这个对象的名称可以根据自己的喜好进行定义,当然最好跟之前的命名规则保持一致,然后我们需要一个Create事件来初始化一些属性:

如图,我们初始化了一个自定义的变量,还用到了GMS2自带的倒计时方法alarm:

spawnrate = 60 ;
alarm[0] = spawnrate ;

这里我们首先自定义了一个spawnrate的变量,这是我们希望用来控制敌人生成时间间隔的一个属性,然后我们把这个变量的值定义给了一个alarm[0],这是GMS2自带的倒计时方法,在添加事件的列表中我们可以看到有专门一个alarm的事件列表:

这意味着,当我们定义的某个倒计时数字等于0时,就会触发对应事件中的代码,而我们之前定义了alarm[0],因此我们直接再添加一个对应的alarm[0]的事件:

我们在这个事件中定义了在游戏场景中随机的位置生成一个新的敌人生成器的实例:

instance_create_layer(random(room_width),random(room_height),"EnemyLayer",obj_enemyspawn)
alarm[0] = spawnrate ;

这上面一句翻译一下就是:

在后面参数所指定图层中指定的位置创建一个指定的实例(随机取一个小于等于后面参数并大于0的值(场景的宽度),随机取一个小于等于后面参数并大于0的值(场景的高度),敌人图层,敌人生成器对象)
alarm[0]的值重新定义为spawnrate的值

第一句就是在场景内随机获取一个x、y坐标,然后在敌人图层的这个位置生成一个敌人生成器对象,而经过我们之前的实验我们知道,生成器对象将会在游戏中自动变成真正的敌人对象。
然后最后我们要记得给alarm[0]重新赋值,因为这一串代码是当alarm[0]倒计时等于0以后触发的,如果我们不重新设定一个值,那这个倒计时永远等于0,那就不会再次被触发,因此需要重新赋值,确保这个倒计时能反复被触发,那敌人也就会源源不断的生成了。
当完成以上内容以后,可以再次打开游戏进行测试,这时候你就可以挑战一下自己到底能得到多少分了,也可以借此跟朋友们一较高下:)


在视频翻译完成一周后,终于图文教程也告一段落了,最近文档翻译的工作稍微有些滞后了,而今天在写这篇的时候发现这最后一节的视频中有一些小问题,中间有一段空白没有声音只有画面在动,虽然不太影响,但总觉得还是不够仔细,很是抱歉……
周末的时候B站又有人给我充了一次电,感激且有一些惶恐,我希望这些东西能帮到更多人,能有那么一些价值,希望大家能更多跟我互动(比如更喜欢什么方向的内容,或是有什么建议之类),给我更多动力,感激不尽~

2017-05-25 00:27
Comments
Write a Comment